//算术工具类，解决小数计算精度不对的问题
/** 测试
	alert(0.1 + 0.2);
	alert(0.1.add(0.2));
	alert(Arith.add(0.1, 0.2));
	alert(1.335.toFixed(2));
	alert(toFixed(1.335, 2));
*/
//加法
Number.prototype.add = function(arg){
    var r1,r2,m;  
    try{r1=this.toString().split(".")[1].length}catch(e){r1=0}
    try{r2=arg.toString().split(".")[1].length}catch(e){r2=0}
    m=Math.pow(10,Math.max(r1,r2));
    return (this*m+arg*m)/m;
}
//减法
Number.prototype.sub = function(arg){
	return this.add(-arg);
}
//乘法 
Number.prototype.mul = function(arg){
    var m=0,s1=this.toString(),s2=arg.toString();
    try{m+=s1.split(".")[1].length}catch(e){}
    try{m+=s2.split(".")[1].length}catch(e){}
    return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);
}
//除法
Number.prototype.div = function (arg){
    var t1=0,t2=0,r1,r2;
    try{t1=this.toString().split(".")[1].length}catch(e){}
    try{t2=arg.toString().split(".")[1].length}catch(e){}
    with(Math){
        r1=Number(this.toString().replace(".",""));
        r2=Number(arg.toString().replace(".",""));
        return (r1/r2)*pow(10,t2-t1);
    }
}

/* ** method **
*  add / subtract / multiply /divide
*
* ** explame **
*  0.1 + 0.2 == 0.30000000000000004 （多了 0.00000000000004）
*  0.2 + 0.4 == 0.6000000000000001  （多了 0.0000000000001）
*  19.9 * 100 == 1989.9999999999998 （少了 0.0000000000002）
*
* Arith.add(0.1, 0.2) >> 0.3
* Arith.multiply(19.9, 100) >> 1990
*
*/
var Arith = function() {
   /*
    * 判断obj是否为一个整数
    */
   function isInteger(obj) {
       return Math.floor(obj) === obj
   }

   /*
    * 将一个浮点数转成整数，返回整数和倍数。如 3.14 >> 314，倍数是 100
    * @param floatNum {number} 小数
    * @return {object}
    *   {times:100, num: 314}
    */
   function toInteger(floatNum) {
       var ret = {times: 1, num: 0}
       if (isInteger(floatNum)) {
           ret.num = floatNum
           return ret;
       }
       var strfi  = floatNum + '';
       var dotPos = strfi.indexOf('.');
       var len    = strfi.substr(dotPos+1).length;
       var times  = Math.pow(10, len);
       var intNum = parseInt(floatNum * times + 0.5, 10);
       ret.times  = times;
       ret.num    = intNum;
       return ret;
   }

   /*
    * 核心方法，实现加减乘除运算，确保不丢失精度
    * 思路：把小数放大为整数（乘），进行算术运算，再缩小为小数（除）
    *
    * @param a {number} 运算数1
    * @param b {number} 运算数2
    * @param digits {number} 精度，保留的小数点数，比如 2, 即保留为两位小数
    * @param op {string} 运算类型，有加减乘除（add/subtract/multiply/divide）
    *
    */
   function operation(a, b, digits, op) {
       var o1 = toInteger(a);
       var o2 = toInteger(b);
       var n1 = o1.num;
       var n2 = o2.num;
       var t1 = o1.times;
       var t2 = o2.times;
       var max = t1 > t2 ? t1 : t2;
       var result = null;
       switch (op) {
           case 'add':
               if (t1 === t2) { // 两个小数位数相同
                   result = n1 + n2;
               } else if (t1 > t2) { // o1 小数位 大于 o2
                   result = n1 + n2 * (t1 / t2);
               } else { // o1 小数位 小于 o2
                   result = n1 * (t2 / t1) + n2;
               }
               return result / max;
           case 'subtract':
               if (t1 === t2) {
                   result = n1 - n2;
               } else if (t1 > t2) {
                   result = n1 - n2 * (t1 / t2);
               } else {
                   result = n1 * (t2 / t1) - n2;
               }
               return result / max;
           case 'multiply':
               result = (n1 * n2) / (t1 * t2);
               return result;
           case 'divide':
               result = (n1 / n2) * (t2 / t1);
               return result;
       }
   }

   // 加减乘除的四个接口
   function add(a, b, digits) {
       return operation(a, b, digits, 'add'); //加法
   }
   function subtract(a, b, digits) {
       return operation(a, b, digits, 'subtract'); //减法
   }
   function multiply(a, b, digits) {
       return operation(a, b, digits, 'multiply'); //乘法
   }
   function divide(a, b, digits) {
       return operation(a, b, digits, 'divide'); //除法
   }
   // exports
   return {
       add: add,
       subtract: subtract,
       multiply: multiply,
       divide: divide
   }
}();
//1.35.toFixed(1) // 1.4 正确
//1.335.toFixed(2) // 1.33  错误
//1.3335.toFixed(3) // 1.333 错误
//1.33335.toFixed(4) // 1.3334 正确
//1.333335.toFixed(5)  // 1.33333 错误
//1.3333335.toFixed(6) // 1.333333 错误
//toFixed 修复
function toFixed(num, s) {
	var fu = '';
	if (num < 0) {
		fu = '-';
		num = -num;
    }
	var times = Math.pow(10, s);
	var des = num * times + 0.5;
	des = parseInt(des, 10) / times;
	return fu +'' + des + '';
}